#!/usr/bin/perl -w
use warnings;
use strict;
use Getopt::Long qw(:config gnu_getopt);

## constant
use constant MIN_DATA_ITEMS => 10;

## user modules
BEGIN {
    use File::Basename;
    my $program_path = File::Basename::dirname($0);
    push @INC, $program_path;
}
use FieldHash;

## options
my ($input, $output, $repository, $help, $quiet);
my $FS = ',';
my $repo;
{
    usage() if @ARGV == 0;
    my %options = (
        'input|i=s'           => \$input,
        'output|o=s'          => \$output,
        'repository|r=s'      => \$repository,
        'field-separator|t=s' => \$FS,
        'quiet|q'             => \$quiet,
        'help|h|?'            => \$help,
    );
    error(-1, "Please run the program with option '--help'.")
        unless (Getopt::Long::GetOptions(%options));
    usage() if $help;
    # options manipulation
    error(-1, "You must specify input file.") unless defined($input);
    error(-1, "You must specify repository file.") unless defined($repository);
    $FS =~ s/\b.t\b/\t/g; $FS =~ s/\b.s\b/ /g;
    $repo = do $repository;
    error(-1, "Cannot `do' the repository file: $repository: $@") if ($@);
}

## open files
open INPUT, '<', $input or error(2, "cannot open input: $input: $!");
if (defined($output)) {
    open OUTPUT, '>', $output or error(3, "cannot open output: $output: $!");
    select OUTPUT;
}

## init data
my ($bin_sort, $settings) = @$repo;

tie my %ic_hash, 'FieldHash';
{
    ## make sure the first lie of the input file
    ## is the table heading line!!!
    chomp(my $line = <INPUT>);
    my @name = split $FS, $line;
    (tied %ic_hash)->name(\@name);
}
# calling sub $bin
my $total_bins = $bin_sort->();
my @bins_count = map( 0, (1 .. $total_bins) );

while (<INPUT>) {
    next if (/^\s*\#\s/); # comment
    chomp; s/\s+$//;
    my @ic_data = split $FS;
    next unless @ic_data >= MIN_DATA_ITEMS(); # empty line, other info line
    (tied %ic_hash)->data(\@ic_data);
    my $bin = sort_bins( \%ic_hash );
    $bins_count[$bin] += 1;
    message(sprintf("[$bin] = (%3d,%3d) [%4d]", $ic_hash{Xadr}, $ic_hash{Yadr}, $ic_hash{ICWaf_No}));
}
message("");
print "Bin\tCount\n";
for my $i (1 .. $#bins_count) {
    printf "Bin-$i\t%d\n", $bins_count[$i];
}

# =====================================================================

close INPUT;
close OUTPUT if defined($output);

# =====================================================================

sub usage {
    (my $PROG = $0) =~ s/.*[\\\/]//;
    print STDERR <<"EO_USAGE";
usage:
    $PROG -i INPUT -r REPOSITORY [ -o OUTPUT -t FS ]
options:
    -i, --input=FILE      specify input data, in CSV format
    -o, --output=FILE     specify output file, if omitted,
                          result will be printed to stdout
    -r, --repository=FILE specify the repository file,
                          which should contains the
                          bins information.
    -t, --field-separator=STRING
                          specify the field separator, which
                          is used for splitting input data
                          and output data fields separation,
                          specify '.t' for a TAB and '.s' for
                          a space
    -h, -?, --help        print this help screen

Send bug report/comment to <\x7a\x78\x69\x61\x40\x68\x65\x6c\x69\x78\x6d\x69\x63\x72\x6f\x2e\x63\x6f\x6d\x2e\x63\x6e>.
\`$PROG\' version 0.1 (2007-7-23 20:48:09)
EO_USAGE
    exit 0 unless defined($_[0]);
    1;
}

sub error {
    my $exit_status = shift;
    my ($package, $filename, $line, $subroutine) = caller();
    $subroutine = 'main' unless defined($subroutine);
    print STDERR "$subroutine: ", @_, "\n";
    print STDERR "from: $filename +$line\n";
    exit $exit_status;
}

sub message {
    return 0 if $quiet;
    print STDERR @_, "\n";
    return 1;
}
